<?php

/**
 * 格式化输出
 * @param $data : 要打印的数据
 * @param bool $exit : 是否终止执行，1=终止，0=继续
 */
function prin($data, $exit = true)
{
	if (is_array($data) or is_object($data)) {
		echo "<pre>" . PHP_EOL;
		print_r($data);
		echo "</pre>" . PHP_EOL;
	} else {
		print_r($data);
	}
	if ($exit) exit;
}

/**
 * 格式化输出
 * @param $data : 要打印的数据
 * @param bool $exit : 是否终止执行，1=终止，0=继续
 */
function vdump($data, $exit = true)
{
	if (is_array($data) or is_object($data)) {
		echo "<pre>" . PHP_EOL;
		var_dump($data);
		echo "</pre>" . PHP_EOL;
	} else {
		var_dump($data);
	}
	if ($exit) exit;
}

function redirect($url)
{
	header('Location: ' . $url);
	exit;
}

function is_mobile()
{
	$agent = isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : '';
	$match = '/Android|webOS|iPhone|iPad|iPod|iOS|Phone|BlackBerry|mobile|Opera Mini|webmate/i';
	if (preg_match($match, $agent)) {
		return true;
	} elseif (isset($_SERVER['HTTP_X_WAP_PROFILE'])) {
		return true;
	} elseif (isset($_SERVER['HTTP_VIA']) and stristr($_SERVER['HTTP_VIA'], "wap")) {
		return true;
	} elseif (isset($_SERVER['HTTP_ACCEPT'])) {
		$ACCEPT = $_SERVER['HTTP_ACCEPT'];
		if ((stripos($ACCEPT, 'vnd.wap.wml') !== false) && (stripos($ACCEPT, 'textml') === false || (stripos($ACCEPT, 'vnd.wap.wml') < stripos($ACCEPT, 'textml')))) {
			return true;
		}
	}
	return false;
}

/**
 * 获取 13 位的毫秒时间戳
 */
function get_microtime()
{
	$microtime = explode(' ', microtime());
	return $microtime[1] . substr($microtime[0], 2, 3);
}

/**
 * 二维数组 多字段排序
 * arr_multisort($array, 'field', SORT_ASC/SORT_DESC);
 * 例如:
	$array = array(
		array('id' => 1, 'name' => 'Abc', 'age' => 10),
		array('id' => 2, 'name' => 'Abc', 'age' => 12),
		array('id' => 4, 'name' => 'Cad', 'age' => 15),
		array('id' => 3, 'name' => 'Cos', 'age' => 16),
		array('id' => 6, 'name' => 'Cos', 'age' => 16),
		array('id' => 5, 'name' => 'Dab', 'age' => 14),
	);
	$data = arr_multisort($array, 'name', SORT_ASC, 'age', SORT_DESC, 'id', SORT_ASC);
 */
function arr_multisort()
{
	$args = func_get_args();
	if (empty($args)) {
		return null;
	}
	$arr = array_shift($args);
	if (!is_array($arr)) {
		throw new Exception("第一个参数不为数组");
	}
	foreach ($args as $key => $field) {
		if (is_string($field)) {
			$temp = array();
			foreach ($arr as $index => $val) {
				$temp[$index] = $val[$field];
			}
			$args[$key] = $temp;
		}
	}
	$args[] = &$arr;//引用值
	call_user_func_array('array_multisort', $args);
	return array_pop($args);
}

/**
 * 把数组变成 url 查询字符串
 * @param $arr : 输入的数组
 * @return string
 */
function build_query($arr = [])
{
	if (empty($arr) || !is_array($arr)) {
		return '';
	}
	foreach ($arr as $k => $v) {
		if ($v === '') {
			unset($arr[$k]);
		}
	}
	return http_build_query($arr, '', '&');
}


/**
 * 将下划线式字符串转换为驼峰式
 * @param $str : 要转换的字符串
 * @param bool $ucfirst : 首字母是否大写，默认为否
 * @return mixed|string
 */
function line_to_hump($str, $ucfirst = false)
{
	$str = ucwords(str_replace('_', ' ', $str));
	$str = str_replace(' ', '', $str);
	$str = $ucfirst ? $str : lcfirst($str);
	return $str;
}

/**
 * 将驼峰式字符串转换为下划线式
 * @param $str：要转换的字符串
 * @return null|string|string[]
 */
function hump_to_line($str)
{
	$str = lcfirst($str);
	$str = preg_replace_callback('#([A-Z]{1,})#', function ($matches) {
		return '_' . strtolower($matches[0]);
	}, $str);
	return $str;
}

/**
 * 递归地将数组键名由下划线式改为为驼峰式
 * $arr：要转换的数组
 * $ucfirst：首字母是否大写，默认为否
 */
function key_to_hump($arr, $ucfirst = false)
{
	if (empty($arr) || !is_array($arr)) {
		return $arr;
	}
	$newArr = array();
	foreach ($arr as $k => $v) {
		$k = line_to_hump($k, $ucfirst);
		$newArr[$k] = is_array($v) ? key_to_hump($v, $ucfirst) : $v;
	}
	return $newArr;
}

/**
 * 递归地将数组键名由驼峰式改为为下划线式
 * $arr：要转换的数组
 */
function key_to_line($arr)
{
	if (empty($arr) || !is_array($arr)) {
		return $arr;
	}
	$newArr = array();
	foreach ($arr as $k => $v) {
		$k = hump_to_line($k);
		$newArr[$k] = is_array($v) ? key_to_line($v) : $v;
	}
	return $newArr;
}

/*
 * 发送 http 请求
 *
 * @param $url : url
 * @param array|string $data : 要发送的数据，如：['id' => 1, 'name' => 'abc']，或 "id=1&name=abc"
 * @param string $method : 请求方法，GET、POST、JSON、FILE
 * @param int $timeout : 超时秒数
 * @param array $options
 *
	$options = [
		'headers' => [
			'Origin: http://www.xxx.com',
			'Referer: https://www.xxx.com/xxx',
			'User-Agent: xxx',
		],
	];
 *
 * @return array: ["code" => 200, "data" => ""]. data 里面是目标URL输出的内容，html 或 json
 */
function http_send($url, $data = [], $method = "get", $timeout = 10, $options = [])
{
	$data = !empty($data) ? $data : [];
	
	if (is_string($data)) {
		$data = trim($data, '?&');
		parse_str($data, $data);
	}
	
	$parseUrl = parse_url($url);
	$origin = $parseUrl['scheme'] . '://' . $parseUrl['host'];
	$queryStr = isset($parseUrl['query']) ? $parseUrl['query'] : "";
	
	$method = strtoupper($method);
	
	$_options = [
		'timeout' => $timeout,
		'http_errors' => true,
		'verify' => false,
		'headers' => [
			'Origin' => $origin,
			'Referer' => $origin,
			'User-Agent' => 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36 SE 2.X MetaSr 1.0',
		],
		'cookies' => "",
	];
	
	if ($options && is_array($options)) {
		if (!empty($options['headers'])) {
			$headers = [];
			foreach ($options['headers'] as $v) {
				list($key, $val) = explode(":", $v, 2);
				$headers[trim($key)] = trim($val);
			}
			$options['headers'] = $headers;
		}
		$options = array_merge($_options, $options);
	} else {
		$options = $_options;
	}
	
	if (!empty($options['proxy'])) {
		$options['proxy'] = [$parseUrl['scheme'] => 'tcp://' . $options['proxy']];
	}
	if (!empty($options['auth'])) {
		$options['auth'] = explode(':', $options['auth']);
	}
	
	$params = [];
	
	if ($method == "GET") {
		if ($queryStr) {
			parse_str($queryStr, $queryArr);
			$data = array_merge($queryArr, $data);
		}
		$params['query'] = $data;
	} elseif ($method == "POST") {
		$params['form_params'] = $data;
	} elseif ($method == "JSON") {
		$params['json'] = $data;
		$method = 'POST';
	} elseif ($method == "FILE") {
		if (empty($data)) {
			return ["code" => 0, "data" => ""];
		}
		
		/*
		 * $data 必须是二维数组，格式为：
			[
			    [
				'name'     => 'field_name',
				'contents' => 'field_val'
			    ],
			    [
				'name'     => 'file_name',
				'contents' => fopen('/path/to/file', 'r')
			    ]
			]
		 */
		
		$params['multipart'] = $data;
		$method = 'POST';
	} else {
		return ["code" => 0, "data" => ""];
	}
	
	$client = new \GuzzleHttp\Client($options);
	
	try {
		$response = $client->request($method, $url, $params);
		$res["code"] = $response->getStatusCode(); // http 状态码
		$res["data"] = $response->getBody()->getContents();
		$res["message"] = '';
	} catch (\GuzzleHttp\Exception\RequestException $re) {
		$res["code"] = $re->getCode();
		$res["message"] = $re->getMessage();
		$res["data"] = '';
	} catch (\Exception $e) {
		$res["code"] = $e->getCode();
		$res["message"] = $e->getMessage();
		$res["data"] = '';
	}
	
	return $res;
}

if (!function_exists('array_get')) {
	/**
	 * 递归获取key值
	 * @param string $str : 以 . 隔开
	 * @param array $array : 多维数组
	 * @return mixed|null
	 */
	function array_get($str, $array)
	{
		$list = explode('.', $str);
		$first = array_shift($list);
		$result = isset($array[$first]) ? $array[$first] : null;
		if ($result && is_array($result) && count($list) > 0) {
			return array_get(join('.', $list), $result);
		}
		return $result;
	}
}

if (!function_exists('array_set')) {
	/**
	 * 动态设置数组值
	 * @param string $str : 以 . 隔开的字符串
	 * @param mixed $val : 值
	 * @param array $array : 引用,目标数据
	 * @return array
	 */
	function array_set($str, $val, &$array)
	{
		$list = explode('.', $str);
		$first = array_shift($list);
		if (count($list) > 0) {
			return array_set(join('.', $list), $val, $array[$first]);
		}
		$array[$first] = $val;
		return $array;
	}
}

if (!function_exists('config'))
{
	function config($name = null)
	{
		return \Config::get($name);
	}
}
